﻿using System;
using SedionFormDesigner.Designer;
using System.Collections.Generic;
using System.Drawing.Design;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.ComponentModel.Design;

namespace SedionFormDesigner.Infrastructure
{
    public class ToolboxPane : System.Windows.Forms.UserControl
    {
        private SedionDesignerHost host;
        private System.Windows.Forms.ListBox customControlsList;
        private List<Type> customControlTypes;
        public const String Pointer = "指针";

        private Int32 selectedIndex;

        public ToolboxPane()
        {
            customControlTypes = new List<Type>();
            customControlsList = new ListBox();
            customControlsList.DrawMode = DrawMode.OwnerDrawVariable;

            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_Button));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_CheckBox));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_ComboBox));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_DataGridView));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_DateTimePicker));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_Label));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_PictureBox));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_RadioButton));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_RichTextBox));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_TextBox));
            //customControlsTypes.Add(typeof(SedionFormDesigner.CusControls.BD_TreeView_Employee));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_Currency));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_Horizon));
            customControlTypes.Add(typeof(SedionFormDesigner.CusControls.BD_Vertical));

            fillToolbox();

            customControlsList.DrawItem += new System.Windows.Forms.DrawItemEventHandler(customControlsList_DrawItem);
            customControlsList.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(customControlsList_MeasureItem);
            customControlsList.KeyDown += new System.Windows.Forms.KeyEventHandler(customControlsList_KeyDown);
            customControlsList.MouseDown += new System.Windows.Forms.MouseEventHandler(customControlsList_MouseDown);

            this.Dock = DockStyle.Fill;
            this.Controls.Add(customControlsList);
            customControlsList.Dock = DockStyle.Fill;
        }

        private void fillToolbox()
        {
            customControlsList.Items.Add(new ToolboxItem
            {
                DisplayName = Pointer,
                Bitmap = new Bitmap(16, 16)
            });

            foreach (Type type in customControlTypes)
            {
                ToolboxItem item = new ToolboxItem(type);
                ToolboxBitmapAttribute attr = TypeDescriptor.GetAttributes(type)[typeof(ToolboxBitmapAttribute)] as ToolboxBitmapAttribute;
                setDisplayName(ref item);

                if (attr != null)
                    item.Bitmap = (Bitmap)attr.GetImage(type.BaseType);

                customControlsList.Items.Add(item);
            }
        }

        private void setDisplayName(ref ToolboxItem item)
        {
            switch (item.DisplayName)
            {
                case "BD_Label":
                    item.DisplayName = "标签";
                    break;
                case "BD_TextBox":
                    item.DisplayName = "文本框";
                    break;
                case "BD_RichTextBox":
                    item.DisplayName = "富文本框";
                    break;
                case "BD_Button":
                    item.DisplayName = "按钮";
                    break;
                case "BD_RadioButton":
                    item.DisplayName = "单选框";
                    break;
                case "BD_CheckBox":
                    item.DisplayName = "复选框";
                    break;
                case "BD_ComboBox":
                    item.DisplayName = "下拉框";
                    break;
                case "BD_PictureBox":
                    item.DisplayName = "图片框";
                    break;
                case "BD_DataGridView":
                    item.DisplayName = "表格";
                    break;
                case "BD_DateTimePicker":
                    item.DisplayName = "日期";
                    break;
                case "BD_Currency":
                    item.DisplayName = "货币";
                    break;
                case "BD_Horizon":
                    item.DisplayName = "水平线";
                    break;
                case "BD_Vertical":
                    item.DisplayName = "垂直线";
                    break;
            }
        }

        public SedionDesignerHost Host
        {
            get
            {
                return host;
            }
            set
            {
                host = value;
            }
        }

        /// <summary>
        ///  接收鼠标事件
        ///  1. 单击
        ///  2. 双击
        ///  3. 拖拽
        /// </summary>
        private void customControlsList_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {

            ListBox lbSender = sender as ListBox;
            Rectangle lastSelectedBounds = lbSender.GetItemRectangle(selectedIndex);

            selectedIndex = lbSender.IndexFromPoint(e.X, e.Y);
            lbSender.SelectedIndex = selectedIndex;

            lbSender.Invalidate(lastSelectedBounds);
            lbSender.Invalidate(lbSender.GetItemRectangle(selectedIndex));

            if (selectedIndex != 0)
            {
                // 双击,添加控件到默认设计器视图上
                if (e.Clicks == 2)
                {
                    IToolboxUser tbu = host.GetDesigner(host.RootComponent) as IToolboxUser;
                    if (tbu != null)
                        tbu.ToolPicked((ToolboxItem)(lbSender.Items[selectedIndex]));
                }
                // 单击或者拖拽
                // 先默认都是先实现拖拽
                // 如果仅仅是单击那么拖拽自己很快就会结束
                else if (e.Clicks < 2)
                {
                    ToolboxItem tbi = lbSender.Items[selectedIndex] as ToolboxItem;
                    IToolboxService tbs = ((IServiceContainer)host).GetService(typeof(IToolboxService)) as IToolboxService;

                    DataObject dataObject = tbs.SerializeToolboxItem(tbi) as DataObject;
                    try
                    {
                        lbSender.DoDragDrop(dataObject, DragDropEffects.Copy);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void customControlsList_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            ListBox lbSender = sender as ListBox;
            Rectangle lastSelectedBounds = lbSender.GetItemRectangle(selectedIndex);
            switch (e.KeyCode)
            {
                case Keys.Up:
                    if (selectedIndex > 0)
                        selectedIndex--;
                    lbSender.SelectedIndex = selectedIndex;
                    // 清理原先的高亮显示
                    lbSender.Invalidate(lastSelectedBounds);
                    // 添加新的
                    lbSender.Invalidate(lbSender.GetItemRectangle(selectedIndex));
                    break;
                case Keys.Down:
                    if (selectedIndex + 1 < lbSender.Items.Count)
                        selectedIndex++;
                    lbSender.SelectedIndex = selectedIndex;
                    lbSender.Invalidate(lastSelectedBounds);
                    lbSender.Invalidate(lbSender.GetItemRectangle(selectedIndex));
                    break;
                case Keys.Enter:
                    // 设置为默认的地址,默认的大小
                    IToolboxUser tbu = host.GetDesigner(host.RootComponent) as IToolboxUser;
                    if (tbu != null)
                        tbu.ToolPicked((ToolboxItem)(lbSender.Items[selectedIndex]));
                    break;
                case Keys.Escape:
                    IMenuCommandService mcs = host.GetService(typeof(IMenuCommandService)) as IMenuCommandService;
                    mcs.GlobalInvoke(System.Windows.Forms.Design.MenuCommands.KeyCancel);
                    break;
            }

        }

        /// <summary>
        ///  测量控件的大小
        /// </summary>
        private void customControlsList_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
        {
            ListBox lbSender = sender as ListBox;
            ToolboxItem tbi = lbSender.Items[e.Index] as ToolboxItem;
            Size textSize = e.Graphics.MeasureString(tbi.DisplayName, lbSender.Font).ToSize();
            e.ItemWidth = tbi.Bitmap.Width + textSize.Width;
            if (tbi.Bitmap.Height > textSize.Height)
                e.ItemHeight = tbi.Bitmap.Height;
            else
                e.ItemHeight = textSize.Height;
        }

        private void customControlsList_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
        {
            ListBox lbSender = sender as ListBox;

            if (selectedIndex == e.Index)
                e.Graphics.FillRectangle(Brushes.LightGray, e.Bounds);
            else
                e.Graphics.FillRectangle(Brushes.White, e.Bounds);

            ToolboxItem tbi = lbSender.Items[e.Index] as ToolboxItem;
            Rectangle BitmapBounds = new Rectangle(e.Bounds.Location.X, e.Bounds.Location.Y, tbi.Bitmap.Width, e.Bounds.Height);
            Rectangle StringBounds = new Rectangle(e.Bounds.Location.X + BitmapBounds.Width, e.Bounds.Location.Y, e.Bounds.Width - BitmapBounds.Width, e.Bounds.Height);
            e.Graphics.DrawImage(tbi.Bitmap, BitmapBounds);
            e.Graphics.DrawString(tbi.DisplayName, lbSender.Font, Brushes.Black, StringBounds);
        }

        /// <summary>
        ///  获得当前选中的项目
        /// </summary>
        public ToolboxItem SelectedTool
        {
            get
            {
                return customControlsList.Items[selectedIndex] as ToolboxItem;
            }
        }

        public ToolboxItemCollection GetTools()
        {
            ToolboxItem[] tools = new ToolboxItem[customControlsList.Items.Count];
            customControlsList.Items.CopyTo(tools, 0);
            return new ToolboxItemCollection(tools);
        }

        public CategoryNameCollection CategoryNames
        {
            get
            {
                String[] categories = new String[1];
                categories[0] = "SedionCustomControls";

                return new CategoryNameCollection(categories);
            }
        }

        public String SelectedCategory
        {
            get
            {
                return "SedionCustomControls";
            }
        }

        /// <summary>
        ///  重置选中项
        /// </summary>
        public void SelectPointer()
        {
            customControlsList.Invalidate(customControlsList.GetItemRectangle(selectedIndex));
            selectedIndex = 0;
            customControlsList.SelectedIndex = 0;
            customControlsList.Invalidate(customControlsList.GetItemRectangle(selectedIndex));
        }
    }
}
